<template>
  <t-card>
    <t-space direction="vertical">
      <common-action-bar :data="actionBarData" @action="onAction"></common-action-bar>

      <t-enhanced-table
        ref="table"
        v-model:expandedTreeNodes="expandedTreeNodes"
        row-key="id"
        :data="list"
        :columns="COLUMNS"
        :loading="isLoading"
        :tree="treeConfig"
        :selected-row-keys="selectedRowKeys"
        bordered
        stripe
        @select-change="tableFn.onSelectChange"
      >
        <template #listorder="{ row }">
          <template v-if="$auth(['content:category:listorder'])">
            <t-input v-model="row.listorder" @blur="tableFn.listorder(row)"></t-input>
          </template>
          <template v-else>{{ row.listorder }}</template>
        </template>
      </t-enhanced-table>
    </t-space>

    <dialog-form
      ref="dialog"
      :list-site-model="listSiteModel"
      :list-category="listCategory"
      @confirm="dialogFn.confirm"
      @remove-file="dialogFn.removeFile"
    ></dialog-form>
  </t-card>
</template>

<script lang="ts" setup>
import { EventType } from 'mitt';
import { EnhancedTableProps, TableRowData } from 'tdesign-vue-next';
import { onMounted, reactive, ref, watch } from 'vue';

import $api from '@/api';
import CommonActionBar, { ActionBarItem } from '@/components/common-action-bar/index.vue';
import { $auth } from '@/directives/auth';
import { $confirm, dialog, isLoading, useCommon } from '@/hooks/common';
import { t } from '@/locales';
import { mitter } from '@/utils/mitt';

import DialogForm from './components/DialogForm.vue';
import { ACTION_BAR_DATA, COLUMNS } from './constants';

const treeConfig: EnhancedTableProps['tree'] = reactive({
  treeNodeColumnIndex: 1,
});
const expandedTreeNodes = ref([]);
const listCategory = ref([]);

const actionBarData = ref([...ACTION_BAR_DATA]);

const API = $api.site.category;
const { list, selectedRowKeys, ...commonIns } = useCommon({
  API,
  page: false,
});

const actionFn: Recordable = {
  ...commonIns.actionFn,
  async reCount() {
    await API.recount();
    tableFn.getList();
  },
  move(item: Recordable) {
    if (item.node.disabled) {
      return;
    }

    $confirm({ theme: 'danger', body: t('pages.category.moveHelp', { target: item.node.catname }) }, async () => {
      const params = {
        from: selectedRowKeys.value,
        to: item.node.id,
      };
      await API.move(params);
      selectedRowKeys.value = [];
      init();
    });
  },
};

const tableFn: Recordable = {
  ...commonIns.tableFn,
  async listorder(row: TableRowData) {
    isLoading.value = true;
    await API.listorder(row.id, row.listorder);
    tableFn.getList();
    isLoading.value = false;
  },
};

const listSiteModel = ref([]);
const getSiteModel = async () => {
  listSiteModel.value = await $api.site.sitemodel.list();
};

const init = async () => {
  await tableFn.getList();
  expandedTreeNodes.value = list.value.map((item) => item.id);

  listCategory.value = [{ catname: t('pages.category.firstLevel'), id: 0 }, ...list.value];
  actionBarData.value[2].options = listCategory.value;
};

const { dialogFn }: Recordable = commonIns;
dialogFn.confirm = async (type: 'add' | 'edit', data: TableRowData) => {
  const method = type === 'add' ? 'add' : 'update';
  try {
    await API[method](data);
    dialog.value.dialogHide();
    init();
  } catch (error) {
    dialog.value.loadingClear();
  }
};

const onAction = (type: string, item: ActionBarItem) => {
  if (type === 'click' && !actionFn[item.key]) {
    console.log(item.key, '不存在');
    return;
  }

  actionFn[item.key](item);
};

// 监听mitter事件，并根据事件类型执行相应的操作
mitter.on('*', (type: EventType, row: TableRowData) => {
  const fnMap: Recordable = {
    add: () => {
      console.log(row);
      dialog.value.dialogShow('addchild', row);
    },
    edit: () => {
      tableFn.edit(row);
    },
    delete: () => {
      tableFn.delete(row);
    },
    display: () => {
      tableFn.display(row, 1 - row.display);
    },
    displayed: async () => {
      row.display = 1 - row.display;
      init();
    },
  };
  if (fnMap[type.toString()]) {
    fnMap[type.toString()]();
  } else {
    console.log(type, '没有监听逻辑');
  }
});

watch(selectedRowKeys, (val) => {
  actionBarData.value[2].disabled = !val.length;

  const setdisebled = (list: any[]) => {
    list.forEach((v: Recordable) => {
      v.disabled = val.includes(v.id);
      if (v.children && v.children.length) {
        setdisebled(v.children);
      }
    });
  };
  setdisebled(listCategory.value);
});

onMounted(async () => {
  getSiteModel();
  init();
});
</script>
